package com.glink.manage.common;

import com.glink.common.exception.GeneralSimpleException;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.core.ZipFile;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

/**
 * @Author: XuM
 * @Description: 解压工具类
 * @Date 2022/12/27
 **/
@Slf4j
public class UnPackUtil {

    /**
     * 设置默认的解压密码，是为了跳过交互，有好的方案可以优化
     * 线程的交互方式测试过，依然需要控制台手动输入交互内容，所以没有使用
     * 设置默认的密码，如果rar包不需要密码，则直接成功，如果rar包需要密码，会解压失败，直接有提示
     */
    private static String unrarCmd_linux = "unrar x  -p0 ";
    private static String unrarCmd_win = "D:\\WinRAR\\unrar x  -p0 ";
    
    /**
     * zip文件解压
     *
     * @param destPath 解压文件路径
     * @param zipFile  压缩文件
     */
    public static void unPackZip(File zipFile, String destPath, String maxFileLength) throws GeneralSimpleException {
        long fileLength = zipFile.length();
        if(fileLength > companyToLong(maxFileLength)){
            log.error("压缩文件已超过{}...", maxFileLength);
        }
        try {
            ZipFile zip = new ZipFile(zipFile);
            /*zip4j默认用GBK编码去解压,这里设置编码为GBK的*/
            zip.setFileNameCharset("GBK");
            log.info("begin unpack zip file....");
            if(zip.isEncrypted()){
                throw new GeneralSimpleException("410188");
            }
            zip.extractAll(destPath);
        } catch (Exception e) {
            if(StringUtils.equals(e.getMessage(), "410188")){
                throw new GeneralSimpleException("410188");
            }else{
                log.error("解压失败：{} ", e.getMessage());    
            }
        }
    }

    /**
     * 将1个RAR文件解压
     * rarFileName 需要解压的RAR文件(必须包含路径信息以及后缀)
     * destDir 解压后的文件放置目录
     */
    public static void unRARFile(File rarFile, String dstDirectoryPath) throws GeneralSimpleException {
        String unrarCmdStr = unrarCmd_linux +  rarFile.getPath() + " " + dstDirectoryPath;
        if(System.getProperty("os.name").toLowerCase().contains("windows")){
            unrarCmdStr = unrarCmd_win +  rarFile.getPath() + " " + dstDirectoryPath;
        }
        log.info("解压rar文件命令：{}", unrarCmdStr);
        try {
            Runtime rt = Runtime.getRuntime();
            Process process = rt.exec(unrarCmdStr);
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
            String s = null;

            while ((s = br.readLine()) != null) {
                // 英文提示和中文提示
                if(s.indexOf("全部错误") >= 0 || s.indexOf("errors") >= 0){
                    throw new GeneralSimpleException("410189");
                }
                System.out.println( "----" + s);
            }
        } catch (Exception e) {
            log.error("解压rar文件失败：{}", e.getMessage());
            if(StringUtils.equals(e.getMessage(), "410189")){
                throw new GeneralSimpleException("410189");
            }else{
                e.printStackTrace();    
            }
            
        }
    }

//    public static void main(String[] args) throws IOException, GeneralSimpleException {
//        String rarDir = "E:\\桌面\\新建文件夹1111.rar";
////        String rarDir = "E:\\桌面\\新建文件夹.rar";
//        String outDir = "E:\\桌面\\test\\";
////        unRar(new File(rarDir),outDir, "5MB");
//        unRARFile(new File(rarDir), outDir);
//    }
    
    /**
     * 带单位的存储转long
     * @param fileLength
     * @return
     */
    private static Long companyToLong(String fileLength){
        Long length = 0L;
        fileLength = fileLength.toLowerCase();
        if(fileLength.endsWith("m") || fileLength.endsWith("mb")){
            fileLength = fileLength.replaceAll("mb", "");
            fileLength = fileLength.replaceAll("m", "");
            long l = Long.parseLong(fileLength);
            length = l * 1024 * 1024;
        }else if(fileLength.endsWith("k") || fileLength.endsWith("kb")){
            fileLength = fileLength.replaceAll("kb", "");
            fileLength = fileLength.replaceAll("k", "");
            long l = Long.parseLong(fileLength);
            length = l * 1024;
        }else if(fileLength.endsWith("g") || fileLength.endsWith("gb")){
            fileLength = fileLength.replaceAll("gb", "");
            fileLength = fileLength.replaceAll("g", "");
            long l = Long.parseLong(fileLength);
            length = l * 1024 * 1024 * 1024;
        }else if(fileLength.endsWith("t") || fileLength.endsWith("tb")){
            fileLength = fileLength.replaceAll("tb", "");
            fileLength = fileLength.replaceAll("t", "");
            long l = Long.parseLong(fileLength);
            length = l * 1024 * 1024 * 1024 * 1024;
        }
        return length;
    }
}
